package org.hepeng.workx.util.proxy;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
import org.hepeng.workx.util.ClassLoaderUtils;
import org.springframework.util.Assert;

import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author he peng
 */

@Deprecated
public class JdkProxyFactory implements ProxyFactory {

    // TODO 有 bug 还需要调试

    @Override
    public Object createProxy(Object target , ProxyInvocationHandler invocationHandler , List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
        Assert.notNull(target , "target must not be null");
        Class<?> targetClass = target.getClass();
        if (ArrayUtils.isEmpty(targetClass.getInterfaces())) {
            throw new IllegalArgumentException(targetClass.getName() + " not implements any interface , unable to use jdk proxy");
        }
        Object proxy = Proxy.newProxyInstance(
                ClassLoaderUtils.getSystemClassLoader(),
                targetClass.getInterfaces(),
                (proxy1, method, args) -> {
                    JdkInvocation invocation = new JdkInvocation(target , method , args);
                    return invocationHandler.invoke(invocation);
                });
        return proxy;
    }

    @Override
    public Object createProxy(Class targetClass, ProxyInvocationHandler invocationHandler, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
        Assert.notNull(targetClass , "targetClass must not be null");
        List<Class<?>> allInterfaces = ClassUtils.getAllInterfaces(targetClass);
        if (CollectionUtils.isEmpty(allInterfaces)) {
            throw new IllegalArgumentException(targetClass.getName() + " not implements any interface , unable to use jdk proxy");
        }

        Class<?>[] allInterfaceClass = new Class[allInterfaces.size()];
        allInterfaceClass = allInterfaces.toArray(allInterfaceClass);
        Object proxy = Proxy.newProxyInstance(
                ClassLoaderUtils.getSystemClassLoader(),
                allInterfaceClass ,
                (proxy1, method, args) -> {
                    JdkInvocation invocation = new JdkInvocation(proxy1 , method , args);
                    return invocationHandler.invoke(invocation);
                });
        return proxy;
    }

    @Override
    public Object createProxy(Class targetClass, List<Class<?>> interfaces, ProxyInvocationHandler invocationHandler, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {

        return null;
    }
}
